import json
import re

import jsonpath

from common.read_yaml import   get_testcase_yaml,Read_yamlData
from common.debugtalk import   DebugTalk
from conf.operationConfig import OperationConfig
from  common.send_request import  Send
from   common.recordlog import  logs
from  common.assertions import  Assrtions

assert_res= Assrtions()

class  BaseRequests:
    def __init__(self):
        self.read=Read_yamlData()
        self.conf=OperationConfig()
        self.send=Send()

    def  replace_load(self,data):
        if  not isinstance(data,str):
            str_data=json.dumps(data,ensure_ascii=False)
        for  i  in  range(str_data.count('${')):
            if   '${'  and  '}' in str_data:
                start_index=str_data.index('$')
                end_index=str_data.index('}',start_index)
                ref_all_params=str_data[start_index:end_index+1]
                print(ref_all_params)
                func_name=ref_all_params[2:ref_all_params.index('(')]
                print(func_name+'我是func_name')
                #print(func_name)
                func_params=ref_all_params[ref_all_params.index('(')+1:ref_all_params.index(')')]
                print(func_params)
                extract_data=getattr(DebugTalk(),func_name)(*func_params.split(',')if  func_params else "")
                print(extract_data)
                print(type(extract_data))
                #print(str_data)
                str_data=str_data.replace(ref_all_params,str(extract_data))
                #print(str_data)
        if  data  and  isinstance(data,dict):
            data=json.loads(str_data)
        else:
            data=str_data
        return  data

    def   specification_yaml(self,case_info):

        #try:
            parmas_type=['data','json','params']
            print('case_info的数据为:',case_info)
            base_url= self.conf.get_section_for_data('api_envi','host')
            url=base_url+case_info['baseInfo']['url']
            print(url)
            api_name=case_info['baseInfo']['api_name']
            print(api_name)
            header=case_info['baseInfo']['header']
            print(header)
            method=case_info['baseInfo']['method']
            for  tc  in  case_info['testCase']:
                case_name=tc.pop('case_name')
                print(case_name)
                validation=tc.pop('validation')
                extract=tc.pop('extract',None)
                extract_list=tc.pop('extract_list',None)
                print(validation)
                for  key,value  in  tc.items():
                    if  key  in  parmas_type:
                        tc[key]=self.replace_load(value)
                #print(tc)
                res =self.send.run_main(url=url,name=api_name,case_name=case_name,header=header,method=method,**tc)
                res_json=res.json()
                if  extract  is  not  None:
                    self.extract_data(extract,response=res.text)
                if  extract_list  is  not None:
                    self.extract_data_list(extract_list,response=res.text)
                assert_res.assert_result(validation,res_json,res.status_code)

    def  extract_data(self,tesecase_extract,response):
            pattenr_lnt=['(.+?)','(.*?)',r'(\d+)',r'(\d*)']
            for  key,value  in  tesecase_extract.items():
                print(key,value)
                for  pat  in  pattenr_lnt:
                    if  pat  in  value:
                        ex_list=re.search(value,response)
                        print(pat+'在这里哈哈')
                        if  pat  in  [r'(\d+',r'(\d*)']:
                            extract_data={key:int(ex_list.group(1))}
                        else:
                            extract_data={key:ex_list.group(1)}
                        print(extract_data)
                        logs.info(f'正则表达式提取到的参数:{extract_data}')
                        self.read.write_yaml_data(extract_data)
                if '$'  in  value:
                    ext_json=jsonpath.jsonpath(json.loads(response),value)[0]
                    if  ext_json:
                        extract_data={key:ext_json}
                    else:
                        extract_data={key:'未提取到数据，该接口返回值为空或者json提取表达式有误！'}
                    logs.info(f'json提取到的参数{extract_data}')
                    self.read.write_yaml_data(extract_data)

    def extract_data_list(self, testcase_extract_list, response):
        """
        提取多个参数，支持正则表达式和json提取，提取结果以列表形式返回
        :param testcase_extract_list: yaml文件中的extract_list信息
        :param response: 接口的实际返回值,str类型
        :return:
        """
        try:
            for key, value in testcase_extract_list.items():
                if "(.+?)" in value or "(.*?)" in value:
                    ext_list = re.findall(value, response, re.S)
                    if ext_list:
                        extract_date = {key: ext_list}
                        logs.info('正则提取到的参数：%s' % extract_date)
                        self.read.write_yaml_data(extract_date)
                if "$" in value:
                    # 增加提取判断，有些返回结果为空提取不到，给一个默认值
                    ext_json = jsonpath.jsonpath(json.loads(response), value)
                    if ext_json:
                        extract_date = {key: ext_json}
                    else:
                        extract_date = {key: "未提取到数据，该接口返回结果可能为空"}
                    logs.info('json提取到参数：%s' % extract_date)
                    self.read.write_yaml_data(extract_date)
        except:
            logs.error('接口返回值提取异常，请检查yaml文件extract_list表达式是否正确！')





if  __name__=='__main__':
    data=get_testcase_yaml('../testcase/productmManager/getProductlist.yaml')[0]
    #print(data)
    F=BaseRequests()
    # F.replace_load(data=data)
    F.specification_yaml(data)





